package cn.gjxblog.proxy.spring.aop.point;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;

/**
 * 这种切点表达式，在早期Spring中的使用较多，一般这么使用：
 *
 *  自己书写的日志切面
 * <bean id="logBeforeAdvice" class="com.fsx.aop.LogBeforeAdvice" />
 *
 * 使用JDK的正则切点~~~~~~
 * <bean id="regexPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
 *     <property name="patterns">
 *          <list>
 *              <value>find.*</value>拦截所有方法名以find开始的方法
 *          </list>
 *     </property>
 * </bean>
 *
 * 切面+切点  组合成一个增强器即可
 * <aop:config>
 *      <aop:advisor advice-ref="logBeforeAdvice" pointcut-ref="regexPointcut"/>
 *  </aop:config>
 *
 *
 *
 * 其实Spring为我们提供了一个简便的Advisor定义，可以方便的让我们同时指定一个JdkRegexpMethodPointcut和其需要对应的Advice，它就是RegexpMethodPointcutAdvisor，这样配置起来非常的方便
 *
 * 	<bean id="logBeforeAdvice" class="com.fsx.aop.LogBeforeAdvice" />
 *     <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
 *         <property name="advice" ref="logBeforeAdvice"/>
 *         <property name="pattern" value="find.*"/>
 *     </bean>
 *
 *
 * @Author guojiaxun
 * @Date 2020/1/2 16:05
 */
public class JdkRegexpMethodPointcutDemo {
	public static void main(String[] args) {
		ProxyFactory proxyFactory = new ProxyFactory(new Person());

		// 环绕通知
		Advice advice = (MethodInterceptor)invocation -> {
			System.out.println("---方法拦截前---");
			Object proceed = invocation.proceed();
			System.out.println("---方法拦截后---");
			return proceed;
		};

		// 切点
		JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
		pointcut.setPattern(".*run.*");


		// 切面
		Advisor advisor = new DefaultPointcutAdvisor(pointcut,advice);

		proxyFactory.addAdvisor(advisor);

		Person proxyPerson = (Person) proxyFactory.getProxy();

		// 执行方法
		proxyPerson.run();


	}
}


class Person{
	public int run() {
		System.out.println("我在run...");
		return 0;
	}

	public void run(int i) {
		System.out.println("我在run...<" + i + ">");
	}

	public void say() {
		System.out.println("我在say...");
	}

	public void sayHi(String name) {
		System.out.println("Hi," + name + ",你好");
	}

	public int say(String name, int i) {
		System.out.println(name + "----" + i);
		return 0;
	}

}


